using System;
using System.ComponentModel;
using System.Threading;

namespace NLite
{
    /// <summary>
    /// 
    /// </summary>
    public static class SynchronizeService
    {
        /// <summary>
        /// 
        /// </summary>
        public static ISynchronizeInvoke SynchronizeObject { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dlgt"></param>
        /// <param name="args"></param>
        public static void Send(this Delegate dlgt, params object[] args)
        {
            if (dlgt != null)
            {
                try
                {
                    if (SynchronizeObject != null && SynchronizeObject.InvokeRequired)
                        SynchronizeObject.Invoke(dlgt, args);
                    else
                    {
                        var sc = SynchronizationContext.Current;
                        if (sc != null)
                            sc.Send(state =>
                            {
                                try
                                {
                                    dlgt.DynamicInvoke(args);
                                }
                                catch (Exception ex)
                                {
                                    ex.RaiseException();
                                }
                            }, null);
                        else
                            dlgt.DynamicInvoke(args);
                    }
                }
                catch (Exception ex)
                {
                    ex.RaiseException();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dlgt"></param>
        /// <param name="args"></param>
        public static void Post(this Delegate dlgt, params object[] args)
        {
            if (dlgt != null)
            {
                try
                {
                    if (SynchronizeObject != null && SynchronizeObject.InvokeRequired)
                        SynchronizeObject.BeginInvoke(dlgt, args);
                    else
                    {
                        var sc = SynchronizationContext.Current;
                        if (sc != null)
                        {
                            sc.Post(state =>
                            {
                                try
                                {
                                    dlgt.DynamicInvoke(args);
                                }
                                catch (Exception e)
                                {
                                    e.RaiseException();
                                }
                            }, null);
                        }
                        else
                        {
                            ThreadPool.QueueUserWorkItem(state =>
                            {
                                try
                                {
                                    dlgt.DynamicInvoke(args);
                                }
                                catch (Exception e)
                                {
                                    e.RaiseException();
                                }
                            });
                        }

                    }
                }
                catch (Exception ex)
                {
                    ex.RaiseException();
                }
            }
        }
    }
}
